import asyncio
import logging
from typing import Tuple
import time

from src.globals.globals import GlobalManage
from src.log.logger import setup_logger
from src.model.event.events import DHTFindNodeEvent
from src.model.message.messages import (
    DHTMessage, NodesMessage, PongMessage, AnnouncePeerResponseMessage
)
from src.routing.routing_table import Node, RoutingTable
from src.rpc.transation_holder import TransactionHolder

class ResponseHandler:
    """DHT响应消息处理器"""

    def __init__(self, transaction_holder: TransactionHolder, unique_id: str):
        self.unique_id: str = unique_id
        self.logger: logging.Logger = setup_logger("response_handler")
        self.transaction_holder: TransactionHolder = transaction_holder
        self.routing_table: RoutingTable = GlobalManage.get_instance().get_routing_table(unique_id)

    def handle_response(self, data: bytes, addr: Tuple[str, int]):
        """处理响应消息"""
        try:
            message = DHTMessage.from_bytes(data=data)
            
            if not self.check_transaction(message):
                self.logger.error(f"事务已过期: {message.transaction_id}")
                return
            
            query_type = self.transaction_holder.get_transaction_type(message.transaction_id)
            self.logger.debug(f"收到响应消息: {query_type} 来自: {addr}")
            
            handler = getattr(self, f"handle_{query_type}_response", None)
            if handler:
                handler(data, addr)
            else:
                self.logger.error(f"未知响应类型: {query_type}")
                
        except Exception as e:
            self.logger.error(f"处理响应消息失败: {e}", exc_info=True)

    def check_transaction(self, message: DHTMessage) -> bool:
        """检查事务是否有效"""
        return self.transaction_holder.has_transaction(message.transaction_id)

    def handle_ping_response(self, data: bytes, addr: Tuple[str, int]):
        """处理ping响应"""
        try:
            pong_message = PongMessage.from_bytes(data=data)
            self.logger.debug(f"解析ping响应成功: {pong_message}")
            
            node = Node(node_id=pong_message.node_id, ip=addr[0], port=addr[1], last_seen=time.time())
            asyncio.create_task(self.routing_table.update_node(node))
            
            GlobalManage.get_instance().publish_event(
                DHTFindNodeEvent(unique_id=self.unique_id, node_id=pong_message.node_id, address=addr)
            )
            
        except Exception as e:
            self.logger.error(f"处理ping响应失败: {e}", exc_info=True)
        finally:
            self.transaction_holder.remove_transaction(pong_message.transaction_id)

    def handle_find_node_response(self, data: bytes,addr:Tuple[str,int]):
        """处理find_node响应"""
        try:
            nodes_message = NodesMessage.from_bytes(data=data)
            self.logger.debug(f"解析find_node响应成功: {nodes_message}")
            
            for node in nodes_message.parse_nodes():
                asyncio.create_task(self.routing_table.update_node(node))
                
        except Exception as e:
            self.logger.error(f"处理find_node响应失败: {e}", exc_info=True)
        finally:
            self.transaction_holder.remove_transaction(nodes_message.transaction_id)

   